/**
 * Copyright 2007-2010 非也
 * All rights reserved. 
 * 
 * This library is free software; you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License v3 as published by the Free Software
 * Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along
 * with this library; if not, see http://www.gnu.org/licenses/lgpl.html.
 *
 */
package org.fireflow2.designer.eclipse.commands.service.java;

import javax.xml.namespace.QName;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.fireflow.engine.modules.script.ScriptContextVariableNames;
import org.fireflow.model.binding.Assignment;
import org.fireflow.model.binding.ServiceBinding;
import org.fireflow.model.binding.impl.AssignmentImpl;
import org.fireflow.model.data.Expression;
import org.fireflow.model.data.impl.ExpressionImpl;
import org.fireflow.model.servicedef.ServiceDef;
import org.fireflow.model.servicedef.impl.JavaInterfaceDef;
import org.fireflow2.designer.eclipse.commands.service.AbstractServiceCreationWizard;
import org.fireflow2.designer.eclipse.modelwrapper.SubProcessWrapper;
import org.fireflow2.designer.eclipse.modelwrapper.basic.ServiceDefWrapper;
import org.fireflow2.designer.eclipse.properties.IPropertyValidateListener;
import org.fireflow2.designer.eclipse.properties.activity.ServiceBindingEditPanel;
import org.fireflow2.designer.eclipse.util.Util4Eclipse;
import org.firesoa.common.schema.NameSpaces;
import org.firesoa.common.util.ScriptLanguages;

/**
 *
 * @author 非也 nychen2000@163.com
 * Fire Workflow 官方网站：www.firesoa.com 或者 www.fireflow.org
 *
 */
public class ConfigInputOutputBindingPage  extends WizardPage implements IPropertyValidateListener{
	private static final String TITLE = "Java调用配置";
	private static final String MESSAGE = "绑定输入输出到流程变量。";
	
	IMethod selectedMethod = null;
	SubProcessWrapper subProcessWrapper = null;
	ServiceBinding serviceBinding = null;
	ServiceDefWrapper serviceDefWrapper = null;
	ServiceBindingEditPanel editPanel = null;
	/**
	 * @param pageName
	 */
	protected ConfigInputOutputBindingPage(String pageName) {
		super(pageName);
		this.setTitle(TITLE);
		this.setMessage(MESSAGE);
		this.setPageComplete(false);
	}
	
    public void setWizard(IWizard newWizard) {
    	super.setWizard(newWizard);
    	subProcessWrapper=((AbstractServiceCreationWizard)newWizard).getSubProcessWrapper();
    	serviceBinding = ((AbstractServiceCreationWizard)newWizard).getServiceBinding();
    	serviceDefWrapper = ((AbstractServiceCreationWizard)newWizard).getServiceDefWrapper();
    }

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
	 */
	public void createControl(Composite parent) {
		FormToolkit formToolkit = new FormToolkit(Display.getCurrent());
		formToolkit.setBackground(ColorConstants.button);
		editPanel = new ServiceBindingEditPanel(false);
		
		editPanel.setFormToolkit(formToolkit);
		editPanel.addServicePropertyModifyListener(this);
		
		Composite composite = (Composite)editPanel.createControl(parent);
		
		this.setControl(composite);

	}
	
	
	
	public void setVisible(boolean visible) {
		// 刷新Methods
		ConfigOperationBindingPage prePage = (ConfigOperationBindingPage)this.getPreviousPage();
		IMethod tempMethod = prePage.getSelectedMethod();
		if(!tempMethod.equals(selectedMethod)){
			selectedMethod = tempMethod;
			//初始化servicebinding中的input assignment 和output assignment
			serviceBinding.getInputAssignments().clear();
			serviceBinding.getOutputAssignments().clear();
			try {
				String[] paramNames = selectedMethod.getParameterNames();
				String[] paramTypes = selectedMethod.getParameterTypes();
				
				for (int i =0;i<paramNames.length;i++){
					String pName = paramNames[i];
					Assignment inputAssignment = new AssignmentImpl();
					
					ExpressionImpl fromExp = new ExpressionImpl();
					fromExp.setLanguage(ScriptLanguages.XPATH.name());
					fromExp.setName("EmptyExpression");
					fromExp.setDisplayName(Expression.EXPRESSION_DISPLAY_NAME_TIP);
					inputAssignment.setFrom(fromExp);
					
					ExpressionImpl toExp = new ExpressionImpl();
					toExp.setLanguage(ScriptLanguages.XPATH.name());
					toExp.setName(pName);
					toExp.setDisplayName(pName);
					toExp.setBody(ScriptContextVariableNames.INPUTS+"/"+pName);
					String typeFullName = Util4Eclipse.signatureToFullTypeName(paramTypes[i]);
					toExp.setDataType(new QName(NameSpaces.JAVA.getUri(),typeFullName,NameSpaces.JAVA.getPrefix()));
					inputAssignment.setTo(toExp);
					
					serviceBinding.getInputAssignments().add(inputAssignment);
				}
				
				//返回值				
				String returnType = selectedMethod.getReturnType();
				if (!Signature.SIG_VOID.equals(returnType)){
					Assignment outputAssignment = new AssignmentImpl();				
					ExpressionImpl fromExp = new ExpressionImpl();
					fromExp.setLanguage(ScriptLanguages.XPATH.name());
					String outputName = JavaInterfaceDef.OUTPUT_NAME_PREFIX + selectedMethod.getElementName();
					fromExp.setName(outputName);
					fromExp.setDisplayName(outputName);
					fromExp.setBody(ScriptContextVariableNames.OUTPUTS+"/"+outputName);
					String typeFullName = Util4Eclipse.signatureToFullTypeName(returnType);
					fromExp.setDataType(new QName(NameSpaces.JAVA.getUri(),typeFullName,NameSpaces.JAVA.getPrefix()));
					outputAssignment.setFrom(fromExp);

					ExpressionImpl toExp = new ExpressionImpl();
					toExp.setLanguage(ScriptLanguages.XPATH.name());
					toExp.setName("EmptyExpression");
					toExp.setDisplayName(Expression.EXPRESSION_DISPLAY_NAME_TIP);
					outputAssignment.setTo(toExp);
					
					serviceBinding.getOutputAssignments().add(outputAssignment);					
				}else{

				}
			} catch (JavaModelException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			editPanel.setSubProcessWrapper(subProcessWrapper);
			editPanel.setInput(serviceBinding);
			editPanel.setServiceDef((ServiceDef)serviceDefWrapper.getWorkflowModelElement());
			editPanel.refresh();
		}
		super.setVisible(visible);
	}
	
	public void onValidateResult(boolean propertyIsOK, String errorMessage,String property,Object newValue,Object oldValue) {
		if (propertyIsOK){
			this.setMessage(MESSAGE);
			this.setErrorMessage(null);
			this.setPageComplete(true);
		}else{
			this.setPageComplete(false);
			this.setMessage(null);
			this.setErrorMessage(errorMessage);
		}
		
	}
}
